package jun.svr.UserSvr;

import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import jun.comm.netkit.JunProtocol;

public class UserSvr {

	//存储SelectionKey的队列
    private static List<SelectionKey> writeQueen = new ArrayList<SelectionKey>();
    static Selector selector = null;
	ServerSocketChannel svrSktChan = null;

	// 监听IP地址
	private static String IP = "127.0.0.1";

	// 监听端口
	private static int PORT = 50080;

	// 超时时间，单位毫秒
//	private static final int TIME_OUT = 3000;
	
	//添加SelectionKey到队列
    public static void addWriteQueen(SelectionKey key){
        synchronized (writeQueen) {
            writeQueen.add(key);
            //唤醒主线程
            selector.wakeup();
        }
    }

	public void init() {
		try {
			// 打开监听信道
			svrSktChan = ServerSocketChannel.open();
			
			// 绑定地址跟端口
			svrSktChan.socket().bind(new InetSocketAddress(PORT));

			// 设置为非阻塞模式
			svrSktChan.configureBlocking(false);

			// 创建选择器
			selector = Selector.open();

			// 将选择器绑定到监听信道,只有非阻塞信道才可以注册选择器.并在注册过程中指出该信道可以进行Accept操作
			svrSktChan.register(selector, SelectionKey.OP_ACCEPT);

			System.out.println("UserSvr服务启动成功，端口:" + PORT);
			System.out.println("等待客户端连接...");
		} catch (Exception e) {
			System.out.println("SVR初始化出错");
		}
	}

	public void run() throws Exception {
		if (selector.isOpen()) {
			while (true) {
				 System.out.println("服务器端：正在监听8989端口");
				int num = selector.select();
				// 等待某信道就绪(或超时)
				if (num > 0) {
					// 创建一个处理协议的实现类,由它来具体操作
					JunProtocol junProtocol = new JunProtocol();
					
					// 取得迭代器.selectedKeys()中包含了每个准备好某一I/O操作的信道的SelectionKey
					Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();
					
					while (keyIter.hasNext()) {
						SelectionKey key = keyIter.next();
						
						try {
							if (key.isAcceptable()) {
								// 有客户端连接请求时
								junProtocol.accept(key);
							}
							
							if (key.isReadable()) {
								// 从客户端读取数据
								junProtocol.read(key);
							}
							
							if (key.isValid() && key.isWritable()) {
								// 客户端可写时
								junProtocol.write(key, "这里是svr端返回的数据");
							}
						} catch (Exception e) {
							// 出现IO异常（如客户端断开连接）时移除处理过的键
							keyIter.remove();
							continue;
						}finally {
							// 移除处理过的键
							keyIter.remove();
						}
						
					}
				}else{
	                synchronized (writeQueen) {
	                    while(writeQueen.size() > 0){
	                        SelectionKey key = writeQueen.remove(0);
	                        //注册写事件
	                        SocketChannel channel = (SocketChannel) key.channel();
	                        Object attachment = key.attachment();
	                        channel.register(selector, SelectionKey.OP_WRITE, attachment);
	                    }
	                }
				}
			}
		}
	}

	public static void main(String[] args) throws Exception {
		UserSvr userSvr = new UserSvr();
		userSvr.init();
		userSvr.run();
	}
}
